home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2000 Spring / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 2).7z / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 2).bin / DXF / samples / multimedia / dplay / src / override / override.cpp < prev    next >
C/C++ Source or Header  |  1999-05-19  |  35KB  |  1,051 lines

  1. //-----------------------------------------------------------------------------
  2. // File: Override.cpp
  3. //
  4. // Desc: Implementation of a DirectPlay launching utility
  5. //
  6. // Copyright (C) 1996-1999 Microsoft Corporation.  All Rights Reserved.
  7. //-----------------------------------------------------------------------------
  8. #define INITGUID
  9. #include <windows.h>
  10. #include <windowsx.h>
  11. #include <objbase.h>
  12. #include <wtypes.h>
  13. #include <cguid.h>
  14. #include "dplay.h"
  15. #include "dplobby.h"
  16. #include "resource.h"
  17.  
  18. #if defined(UNICODE) || defined(_UNICODE)
  19. #error This app does not support UNICODE
  20. #endif
  21.  
  22.  
  23.  
  24.  
  25. //-----------------------------------------------------------------------------
  26. // Constants
  27. //-----------------------------------------------------------------------------
  28. #define NAMEMAX         200     // string size
  29. #define TIMERID         1       // timer ID to use
  30. #define TIMERINTERVAL   1000    // timer interval
  31. #define MAXSTRLEN       200     // maximum size of temp strings
  32.  
  33. struct STATUSCONTEXT
  34. {
  35.     LPDIRECTPLAY4A pDP;
  36.     GUID           guidInstance;
  37. };
  38.  
  39. // guid for this application
  40. DEFINE_GUID(OVERRIDE_GUID, 
  41. 0x126e6180, 0xd307, 0x11d0, 0x9c, 0x4f, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e );
  42.  
  43.  
  44.  
  45.  
  46. //-----------------------------------------------------------------------------
  47. // Function prototypes
  48. //-----------------------------------------------------------------------------
  49. BOOL CALLBACK OverrideWndProc( HWND hWnd, UINT uMsg, WPARAM wParam,
  50.                                LPARAM lParam );
  51. BOOL CALLBACK SessionsWndProc( HWND hWnd, UINT uMsg, WPARAM wParam,
  52.                                LPARAM lParam );
  53. BOOL FAR PASCAL EnumConnectionsCallback( const GUID* pSPGUID, VOID* pConnection,
  54.                                          DWORD dwConnectionSize,
  55.                                          const DPNAME* pName, DWORD dwFlags,
  56.                                          VOID* pContext );
  57. HRESULT InitializeOverrideWindow( HWND hWnd, LPDIRECTPLAYLOBBY3A* ppDPLobby );
  58. VOID    DestroyOverrideWindow( HWND hWnd, LPDIRECTPLAY4A pDP,
  59.                                LPDIRECTPLAYLOBBY3A pDPLobby );
  60. HRESULT UpdateAddressInfo( HWND hWnd, LPDIRECTPLAYLOBBY3A pDPLobby );
  61. HRESULT DoHostOrJoin( HINSTANCE hInstance, HWND hWnd,
  62.                       LPDIRECTPLAYLOBBY3A pDPLobby, BOOL bHost,
  63.                       LPDIRECTPLAY4A* ppDP );
  64. HRESULT GetServiceProviderGuid( HWND hWnd, GUID* pServiceProviderGUID );
  65. VOID    DeleteServiceProviderCombo( HWND hWnd );
  66. HRESULT FillModemComboBox( HWND hWnd, LPDIRECTPLAYLOBBY3A pDPLobby );
  67. BOOL    DlgItemIsChecked( HWND hDlg, int nIDDlgItem );
  68. VOID    EnableDlgButton( HWND hDlg, int nIDDlgItem, BOOL bEnable );
  69. VOID    ErrorBox( LPSTR strErrorStr, HRESULT hr );
  70.  
  71.  
  72.  
  73.  
  74. //-----------------------------------------------------------------------------
  75. // Name: WinMain()
  76. // Desc: Main windows entry point.
  77. //-----------------------------------------------------------------------------
  78. int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  79.                     LPSTR lpCmdLine, int nCmdShow )
  80. {
  81.     // Initialize COM library
  82.     HRESULT hr = CoInitialize( NULL );
  83.     if( FAILED(hr) )
  84.     {
  85.         ErrorBox( "CoInitialize failed. Error 0x%0X", hr );
  86.         return 0;
  87.     }
  88.  
  89.     int iResult = DialogBoxParam( hInstance,
  90.                                   MAKEINTRESOURCE(IDD_OVERRIDEDIALOG), NULL,
  91.                                   (DLGPROC)OverrideWndProc, (LPARAM)hInstance );
  92.  
  93.     // Uninitialize the COM library
  94.     CoUninitialize();
  95.  
  96.     return iResult;
  97. }
  98.  
  99.  
  100.  
  101.  
  102. //-----------------------------------------------------------------------------
  103. // Name: OverrideWndProc()
  104. // Desc: Message callback function for Override dialog.
  105. //-----------------------------------------------------------------------------
  106. BOOL CALLBACK OverrideWndProc( HWND hWnd, UINT uMsg, WPARAM wParam,
  107.                                LPARAM lParam )
  108. {
  109.     static HINSTANCE           hInstance;
  110.     static LPDIRECTPLAY4A      pDP;
  111.     static LPDIRECTPLAYLOBBY3A pDPLobby;
  112.     HRESULT hr;
  113.  
  114.     switch( uMsg )
  115.     {
  116.         case WM_INITDIALOG:
  117.             // Save the instance handle
  118.             hInstance = (HINSTANCE)lParam;
  119.             
  120.             // Initialize dialog with launcher information
  121.             pDP = NULL;
  122.             pDPLobby = NULL;
  123.             hr = InitializeOverrideWindow( hWnd, &pDPLobby );
  124.             if( FAILED(hr) )
  125.                 SetDlgItemText( hWnd, IDC_STATUSEDIT, "Could not initialize DirectPlay" );
  126.             return TRUE;
  127.  
  128.         case WM_DESTROY:
  129.             // Destroy launcher information in dialog
  130.             DestroyOverrideWindow( hWnd, pDP, pDPLobby );
  131.             break;  // continue with default handling
  132.  
  133.         case WM_COMMAND:
  134.             switch( LOWORD(wParam) )
  135.             {
  136.                 case IDC_SPCOMBO:
  137.                     switch (HIWORD(wParam))
  138.                     {
  139.                         case CBN_SELCHANGE:
  140.                             UpdateAddressInfo( hWnd, pDPLobby );
  141.                             return TRUE;
  142.                     }
  143.                     break;
  144.  
  145.                 case IDC_HOSTBUTTON:
  146.                     SetDlgItemText( hWnd, IDC_STATUSEDIT, "Hosting..." );
  147.                     hr = DoHostOrJoin( hInstance, hWnd, pDPLobby, TRUE, &pDP );
  148.                     if( FAILED(hr) )
  149.                         SetDlgItemText( hWnd, IDC_STATUSEDIT, "Failed to host" );
  150.                     else
  151.                         SetDlgItemText( hWnd, IDC_STATUSEDIT, "Host successfull" );
  152.                     return TRUE;
  153.  
  154.             case IDC_JOINBUTTON:
  155.                 SetDlgItemText( hWnd, IDC_STATUSEDIT, "Joining..." );
  156.                 hr = DoHostOrJoin( hInstance, hWnd, pDPLobby, FALSE, &pDP );
  157.                 if FAILED(hr)
  158.                     SetDlgItemText( hWnd, IDC_STATUSEDIT, "Failed to join" );
  159.                 else
  160.                     SetDlgItemText( hWnd, IDC_STATUSEDIT, "Join successfull" );
  161.                 return TRUE;
  162.  
  163.             case IDCANCEL:
  164.                 // Return failure
  165.                 EndDialog( hWnd, TRUE );
  166.                 return TRUE;
  167.         }
  168.         break;
  169.     }
  170.  
  171.     // Allow for default processing
  172.     return FALSE;
  173. }
  174.  
  175.  
  176.  
  177.  
  178. //-----------------------------------------------------------------------------
  179. // Name: InitializeOverrideWindow()
  180. // Desc: 
  181. //-----------------------------------------------------------------------------
  182. HRESULT InitializeOverrideWindow( HWND hWnd, LPDIRECTPLAYLOBBY3A* ppDPLobby )
  183. {
  184.     LPDIRECTPLAY4A      pDP      = NULL;
  185.     LPDIRECTPLAYLOBBY3A pDPLobby = NULL;
  186.     HRESULT hr;
  187.         
  188.     // Create a temporary ANSI DirectPlay interface
  189.     hr = CoCreateInstance( CLSID_DirectPlay, NULL, CLSCTX_INPROC_SERVER, 
  190.                            IID_IDirectPlay4A, (VOID**)&pDP );
  191.     if( FAILED(hr) )
  192.         return hr;
  193.  
  194.     // Get ANSI DirectPlayLobby interface
  195.     hr = CoCreateInstance( CLSID_DirectPlayLobby, NULL, CLSCTX_INPROC_SERVER,
  196.                            IID_IDirectPlayLobby3A, (VOID**)&pDPLobby );
  197.     if( FAILED(hr) )
  198.     {
  199.         pDP->Release();
  200.         return hr;
  201.     }
  202.  
  203.     // Put all the service providers in combo box
  204.     pDP->EnumConnections( NULL, EnumConnectionsCallback, hWnd, 0 );
  205.     SendDlgItemMessage( hWnd, IDC_SPCOMBO, CB_SETCURSEL, 0, 0 );
  206.  
  207.     // Fill modem combo box with available modems
  208.     FillModemComboBox( hWnd, pDPLobby );
  209.  
  210.     // Limit Port number edit field to 5 digits
  211.     SendDlgItemMessage( hWnd, IDC_PORTEDIT, EM_LIMITTEXT, 5, 0 );
  212.  
  213.     // Update display first service provider
  214.     UpdateAddressInfo( hWnd, pDPLobby );
  215.  
  216.     // Return the ANSI lobby interface
  217.     *ppDPLobby = pDPLobby;
  218.  
  219.     pDP->Release();
  220.     return DP_OK;
  221. }
  222.  
  223.  
  224.  
  225.  
  226. //-----------------------------------------------------------------------------
  227. // Name: DestroyOverrideWindow()
  228. // Desc: 
  229. //-----------------------------------------------------------------------------
  230. VOID DestroyOverrideWindow( HWND hWnd, LPDIRECTPLAY4A pDP, 
  231.                             LPDIRECTPLAYLOBBY3A pDPLobby )
  232. {
  233.     // Delete combo box data items
  234.     DeleteServiceProviderCombo( hWnd );
  235.  
  236.     // Release the dplay interface
  237.     if( pDP )
  238.         pDP->Release();
  239.  
  240.     // Release the lobby interface
  241.     if( pDPLobby )
  242.         pDPLobby->Release();
  243. }
  244.  
  245.  
  246.  
  247.  
  248. //-----------------------------------------------------------------------------
  249. // Name: EnumConnectionsCallback()
  250. // Desc: Enumerates service providers registered with DirectPlay.
  251. //-----------------------------------------------------------------------------
  252. BOOL FAR PASCAL EnumConnectionsCallback( const GUID* pSPGUID, VOID* pConnection,
  253.                                          DWORD dwConnectionSize,
  254.                                          const DPNAME* pName, DWORD dwFlags,
  255.                                          VOID* pContext )
  256. {
  257.     HWND    hWnd = (HWND)pContext;
  258.     LRESULT iIndex;
  259.     GUID*   pGuid;
  260.  
  261.     // Store service provider name in combo box
  262.     iIndex = SendDlgItemMessage( hWnd, IDC_SPCOMBO, CB_ADDSTRING, 0,
  263.                                  (LPARAM)pName->lpszShortNameA );
  264.     if( iIndex == CB_ERR )
  265.         return TRUE;
  266.  
  267.     // Make space for application GUID
  268.     pGuid = (GUID*)GlobalAllocPtr( GHND, sizeof(GUID) );
  269.     if( pGuid == NULL )
  270.         return TRUE;
  271.  
  272.     // Store pointer to GUID in combo box
  273.     *pGuid = *pSPGUID;
  274.     SendDlgItemMessage( hWnd, IDC_SPCOMBO, CB_SETITEMDATA, (WPARAM)iIndex,
  275.                         (LPARAM)pGuid );
  276.  
  277.     return TRUE;
  278. }
  279.  
  280.  
  281.  
  282.  
  283. //-----------------------------------------------------------------------------
  284. // Name: GetServiceProviderGuid()
  285. // Desc: 
  286. //-----------------------------------------------------------------------------
  287. HRESULT GetServiceProviderGuid( HWND hWnd, GUID* pServiceProviderGUID )
  288. {
  289.     LONG iIndex;
  290.  
  291.     // Get guid for service provider
  292.     iIndex = SendDlgItemMessage( hWnd, IDC_SPCOMBO, CB_GETCURSEL, 0, 0 );
  293.     if( iIndex == CB_ERR )
  294.         return DPERR_GENERIC;
  295.  
  296.     iIndex = SendDlgItemMessage( hWnd, IDC_SPCOMBO, CB_GETITEMDATA,
  297.                                  (WPARAM)iIndex, 0 );
  298.     if( (iIndex == CB_ERR) || (iIndex == 0) )
  299.         return DPERR_GENERIC;
  300.  
  301.     *pServiceProviderGUID = *((GUID*)iIndex);
  302.  
  303.     return DP_OK;
  304. }
  305.  
  306.  
  307.  
  308.  
  309. //-----------------------------------------------------------------------------
  310. // Name: DeleteServiceProviderCombo()
  311. // Desc: 
  312. //-----------------------------------------------------------------------------
  313. VOID DeleteServiceProviderCombo( HWND hWnd )
  314. {
  315.     WPARAM i;
  316.     LONG   pData;
  317.     
  318.     // Destroy the data stored with each combo box item
  319.     i = 0;
  320.     while( TRUE )
  321.     {
  322.         // Get data pointer stored with item
  323.         pData = SendDlgItemMessage( hWnd, IDC_SPCOMBO, CB_GETITEMDATA, i, 0 );
  324.         if( pData == CB_ERR )           // error getting data
  325.             break;
  326.  
  327.         if( pData )                     // data to delete
  328.             GlobalFreePtr( (VOID*)pData );
  329.         
  330.         i++;
  331.     }
  332.  
  333.     // Delete all items in list
  334.     SendDlgItemMessage( hWnd, IDC_SPCOMBO, CB_RESETCONTENT, 0, 0 );
  335. }
  336.  
  337.  
  338.  
  339.  
  340. //-----------------------------------------------------------------------------
  341. // Name: DeleteSessionInstanceList()
  342. // Desc: 
  343. //-----------------------------------------------------------------------------
  344. VOID DeleteSessionInstanceList( HWND hWnd )
  345. {
  346.     WPARAM i;
  347.     LONG   pData;
  348.     
  349.     // Destroy the GUID's stored with each session name
  350.     i = 0;
  351.     while( TRUE )
  352.     {
  353.         // Get data pointer stored with item
  354.         pData = SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_GETITEMDATA,
  355.                                     i, 0 );
  356.         if( pData == CB_ERR )           // error getting data
  357.             break;
  358.         
  359.         if( pData )                     // data to delete
  360.             GlobalFreePtr( (VOID*)pData );
  361.  
  362.         i++;
  363.     }
  364.  
  365.     // Delete all items in list
  366.     SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_RESETCONTENT, 0, 0 );
  367. }
  368.  
  369.  
  370.  
  371.  
  372. //-----------------------------------------------------------------------------
  373. // Name: 
  374. // Desc: 
  375. //-----------------------------------------------------------------------------
  376. VOID SelectSessionInstance( HWND hWnd, GUID* pSessionInstanceGUID )
  377. {
  378.     WPARAM i, iIndex;
  379.     LONG   pData;
  380.     
  381.     // Loop over the GUID's stored with each session name
  382.     // to find the one that matches what was passed in
  383.     i = 0;
  384.     iIndex = 0;
  385.     while( TRUE )
  386.     {
  387.         // Get data pointer stored with item
  388.         pData = SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_GETITEMDATA,
  389.                                     i, 0 );
  390.         if( pData == CB_ERR )           // error getting data
  391.             break;
  392.  
  393.         if( pData == 0 )                // no data to compare to
  394.             continue;
  395.  
  396.         // Guid matches
  397.         if( IsEqualGUID( *pSessionInstanceGUID, *((GUID*)pData) ) )
  398.         {
  399.             iIndex = i;                 // store index of this string
  400.             break;
  401.         }
  402.  
  403.         i++;
  404.     }
  405.  
  406.     // Select this item
  407.     SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_SETCURSEL, iIndex, 0);
  408. }
  409.  
  410.  
  411.  
  412.  
  413. //-----------------------------------------------------------------------------
  414. // Name: GetSessionInstanceGuid()
  415. // Desc: 
  416. //-----------------------------------------------------------------------------
  417. HRESULT GetSessionInstanceGuid( HWND hWnd, GUID* pSessionInstanceGUID )
  418. {
  419.     LONG iIndex;
  420.  
  421.     // Get guid for session
  422.     iIndex = SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_GETCURSEL, 0, 0 );
  423.     if( iIndex == LB_ERR )
  424.         return DPERR_GENERIC;
  425.  
  426.     iIndex = SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_GETITEMDATA,
  427.                                  (WPARAM) iIndex, 0 );
  428.     if( (iIndex == LB_ERR) || (iIndex == 0) )
  429.         return DPERR_GENERIC;
  430.  
  431.     *pSessionInstanceGUID = *((GUID*)iIndex );
  432.  
  433.     return DP_OK;
  434. }
  435.  
  436.  
  437.  
  438.  
  439. //-----------------------------------------------------------------------------
  440. // Name: EnumSessionsCallback()
  441. // Desc: 
  442. //-----------------------------------------------------------------------------
  443. BOOL FAR PASCAL EnumSessionsCallback( const DPSESSIONDESC2* pSessionDesc,
  444.                                       DWORD* pdwTimeOut, DWORD dwFlags,
  445.                                       VOID* pContext )
  446. {
  447.     HWND  hWnd = (HWND)pContext;
  448.     GUID* pGuid;
  449.     LONG  iIndex;
  450.  
  451.     // See if last session has been enumerated
  452.     if( dwFlags & DPESC_TIMEDOUT )
  453.         return FALSE;
  454.  
  455.     // Store session name in list
  456.     iIndex = SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_ADDSTRING, 
  457.                                  0, (LPARAM)pSessionDesc->lpszSessionNameA );
  458.     if( iIndex == LB_ERR )
  459.         return TRUE;
  460.  
  461.     // Make space for session instance guid
  462.     pGuid = (GUID*)GlobalAllocPtr( GHND, sizeof(GUID) );
  463.     if( pGuid == NULL )
  464.         return TRUE;
  465.  
  466.     // Store pointer to guid in list
  467.     *pGuid = pSessionDesc->guidInstance;
  468.     SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_SETITEMDATA, (WPARAM)iIndex,
  469.                         (LPARAM)pGuid );
  470.  
  471.     return TRUE;
  472. }
  473.  
  474.  
  475.  
  476.  
  477. //-----------------------------------------------------------------------------
  478. // Name: SessionsWndProc()
  479. // Desc: 
  480. //-----------------------------------------------------------------------------
  481. BOOL CALLBACK SessionsWndProc( HWND hWnd, UINT uMsg, WPARAM wParam,
  482.                                LPARAM lParam )
  483. {
  484.     static STATUSCONTEXT* pContext;
  485.     static LPDIRECTPLAY4A pDP;
  486.     static UINT           idTimer;
  487.     static BOOL           bInsideEnumSessions;
  488.     DPSESSIONDESC2 sessionDesc;
  489.     GUID           guidSessionInstance;
  490.     LONG           iIndex;
  491.     HRESULT        hr;
  492.  
  493.     switch( uMsg )
  494.     {
  495.         case WM_INITDIALOG:
  496.             pContext = (STATUSCONTEXT*)lParam;
  497.             pDP = pContext->pDP;
  498.             bInsideEnumSessions = FALSE;
  499.  
  500.             // Can't join until there is a session
  501.             EnableDlgButton( hWnd, IDC_JOINSESSIONBUTTON, FALSE );
  502.  
  503.             // Set a timer to refresh the session list
  504.             idTimer = SetTimer( hWnd, TIMERID, TIMERINTERVAL, NULL );
  505.             break;
  506.  
  507.         case WM_DESTROY:
  508.             if( idTimer )
  509.             {
  510.                 KillTimer( hWnd, idTimer ); 
  511.                 idTimer = 0;
  512.             }
  513.             DeleteSessionInstanceList( hWnd );
  514.             break;
  515.  
  516.         case WM_TIMER:
  517.             // Make sure we don't re-enter EnumSessions
  518.             if( bInsideEnumSessions )
  519.                 break;
  520.  
  521.             // Get guid of currently selected session
  522.             guidSessionInstance = GUID_NULL;
  523.             hr = GetSessionInstanceGuid( hWnd, &guidSessionInstance );
  524.  
  525.             // Delete existing session list
  526.             DeleteSessionInstanceList( hWnd );
  527.  
  528.             // Enum sessions
  529.             ZeroMemory( &sessionDesc, sizeof(DPSESSIONDESC2) );
  530.             sessionDesc.dwSize = sizeof(DPSESSIONDESC2);
  531.             sessionDesc.guidApplication = OVERRIDE_GUID;
  532.  
  533.             bInsideEnumSessions = TRUE;
  534.             hr = pDP->EnumSessions( &sessionDesc, 0, EnumSessionsCallback,
  535.                                     hWnd, DPENUMSESSIONS_AVAILABLE |
  536.                                           DPENUMSESSIONS_ASYNC |
  537.                                           DPENUMSESSIONS_RETURNSTATUS );
  538.             bInsideEnumSessions = FALSE;
  539.  
  540.             // Select the session that was previously selected
  541.             SelectSessionInstance( hWnd, &guidSessionInstance );
  542.  
  543.             // Hilight "Join" button only if there are sessions to join
  544.             iIndex = SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_GETCOUNT,
  545.                                          0, 0 );
  546.  
  547.             EnableDlgButton( hWnd, IDC_JOINSESSIONBUTTON,
  548.                              (iIndex > 0) ? TRUE : FALSE );
  549.  
  550.             switch( hr )
  551.             {
  552.                 case DP_OK:
  553.                     SetDlgItemText( hWnd, IDC_SESSIONSTATUSEDIT, "Searching for sessions..." );
  554.                     break;
  555.  
  556.                 case DPERR_CONNECTING:
  557.                     SetDlgItemText( hWnd, IDC_SESSIONSTATUSEDIT, "Making connection..." );
  558.                     break;
  559.  
  560.                 case DPERR_NOCONNECTION:
  561.                     SetDlgItemText( hWnd, IDC_SESSIONSTATUSEDIT, "Connection failed" );
  562.                     KillTimer( hWnd, idTimer ); 
  563.                     idTimer = 0;
  564.                     break;
  565.  
  566.                 default:
  567.                     SetDlgItemText( hWnd, IDC_SESSIONSTATUSEDIT, "Error making connection" );
  568.                     KillTimer( hWnd, idTimer ); 
  569.                     idTimer = 0;
  570.                     break;
  571.             }
  572.             break;
  573.         
  574.         case WM_COMMAND:
  575.             switch( LOWORD(wParam) )
  576.             {
  577.                 case IDC_JOINSESSIONBUTTON:
  578.                     // Return guid of session to join
  579.                     hr = GetSessionInstanceGuid( hWnd, &pContext->guidInstance );
  580.                     if( SUCCEEDED(hr) )
  581.                         EndDialog( hWnd, TRUE );
  582.                     break;
  583.  
  584.                 case IDCANCEL:
  585.                     // Return failure
  586.                     EndDialog( hWnd, FALSE );
  587.                     break;
  588.             }
  589.             break;
  590.     }
  591.  
  592.     // Allow for default processing
  593.     return FALSE;
  594. }
  595.  
  596.  
  597.  
  598.  
  599. //-----------------------------------------------------------------------------
  600. // Name: UpdateAddressInfo()
  601. // Desc: Updates address information elements in dialog. Calls
  602. //       EnumAddressTypes() to determine what address information should be
  603. //       displayed and arranges dialog to display and collect the needed
  604. //       information.
  605. //-----------------------------------------------------------------------------
  606. HRESULT UpdateAddressInfo( HWND hWnd, LPDIRECTPLAYLOBBY3A pDPLobby )
  607. {
  608.     GUID    guidServiceProvider;
  609.     HRESULT hr;
  610.  
  611.     // Clear and hide address dialog items
  612.     ShowWindow( GetDlgItem(hWnd, IDC_PHONEEDIT), SW_HIDE );
  613.     ShowWindow( GetDlgItem(hWnd, IDC_PHONEEDITLABEL), SW_HIDE );
  614.     ShowWindow( GetDlgItem(hWnd, IDC_MODEMCOMBO), SW_HIDE );
  615.     ShowWindow( GetDlgItem(hWnd, IDC_MODEMCOMBOLABEL), SW_HIDE );
  616.     ShowWindow( GetDlgItem(hWnd, IDC_TCPEDIT), SW_HIDE );
  617.     ShowWindow( GetDlgItem(hWnd, IDC_TCPEDITLABEL), SW_HIDE );
  618.     ShowWindow( GetDlgItem(hWnd, IDC_PORTEDIT), SW_HIDE );
  619.     ShowWindow( GetDlgItem(hWnd, IDC_PORTEDITLABEL), SW_HIDE );
  620.     ShowWindow( GetDlgItem(hWnd, IDC_IPXLABEL), SW_HIDE );
  621.     ShowWindow( GetDlgItem(hWnd, IDC_SERVICEPROVIDERLABEL), SW_HIDE );
  622.  
  623.     // Get currently selected service provider
  624.     hr = GetServiceProviderGuid( hWnd, &guidServiceProvider );
  625.     if( FAILED(hr) )
  626.         return hr;
  627.  
  628.     if( IsEqualGUID( guidServiceProvider, DPSPGUID_MODEM ) )
  629.     {
  630.         // Modem service provider
  631.         // Show edit control to collect phone number and modem
  632.         ShowWindow( GetDlgItem(hWnd, IDC_PHONEEDIT), SW_SHOW );
  633.         ShowWindow( GetDlgItem(hWnd, IDC_PHONEEDITLABEL), SW_SHOW );
  634.         ShowWindow( GetDlgItem(hWnd, IDC_MODEMCOMBO), SW_SHOW );
  635.         ShowWindow( GetDlgItem(hWnd, IDC_MODEMCOMBOLABEL), SW_SHOW );
  636.     }
  637.     else if( IsEqualGUID( guidServiceProvider, DPSPGUID_TCPIP ) )
  638.     {
  639.         // Internet TCP/IP service provider
  640.         // Show edit control to collect IP address and port number
  641.         ShowWindow( GetDlgItem(hWnd, IDC_TCPEDIT), SW_SHOW );
  642.         ShowWindow( GetDlgItem(hWnd, IDC_TCPEDITLABEL), SW_SHOW );
  643.         ShowWindow( GetDlgItem(hWnd, IDC_PORTEDIT), SW_SHOW );
  644.         ShowWindow( GetDlgItem(hWnd, IDC_PORTEDITLABEL), SW_SHOW );
  645.     }
  646.     else if( IsEqualGUID( guidServiceProvider, DPSPGUID_IPX ) )
  647.     {
  648.         // IPX service provider
  649.         // No address info is needed, so just display a string
  650.         ShowWindow( GetDlgItem(hWnd, IDC_IPXLABEL), SW_SHOW );
  651.     }
  652.     else
  653.     {
  654.         // Anything else, let service provider collect settings, if any
  655.         ShowWindow( GetDlgItem(hWnd, IDC_SERVICEPROVIDERLABEL), SW_SHOW );
  656.     }
  657.  
  658.     return hr;
  659. }
  660.  
  661.  
  662.  
  663.  
  664. //-----------------------------------------------------------------------------
  665. // Name: CreateServiceProviderAddress()
  666. // Desc: 
  667. //-----------------------------------------------------------------------------
  668. HRESULT CreateServiceProviderAddress( HWND hWnd, LPDIRECTPLAYLOBBY3A pDPLobby,
  669.                                       VOID** ppAddress, DWORD* pdwAddressSize )
  670. {
  671.     DPCOMPOUNDADDRESSELEMENT addressElements[3];
  672.     CHAR    strIPAddressString[NAMEMAX];
  673.     CHAR    strPhoneNumberString[NAMEMAX];
  674.     CHAR    strModemString[NAMEMAX];
  675.     VOID*   pAddress = NULL;
  676.     DWORD   dwAddressSize = 0;
  677.     DWORD   dwElementCount;
  678.     GUID    guidServiceProvider;
  679.     WORD    wPort;
  680.     HRESULT hr;
  681.  
  682.     // Get currently selected service provider
  683.     hr = GetServiceProviderGuid( hWnd, &guidServiceProvider );
  684.     if( FAILED(hr) )
  685.         return hr;
  686.  
  687.     dwElementCount = 0;
  688.  
  689.     if( IsEqualGUID( guidServiceProvider, DPSPGUID_MODEM ) )
  690.     {
  691.         // Modem needs a service provider, a phone number string and a modem string
  692.  
  693.         // Dervice provider
  694.         addressElements[dwElementCount].guidDataType = DPAID_ServiceProvider;
  695.         addressElements[dwElementCount].dwDataSize   = sizeof(GUID);
  696.         addressElements[dwElementCount].lpData       = (VOID*)&DPSPGUID_MODEM;
  697.         dwElementCount++;
  698.  
  699.         // Sdd a modem string if available
  700.         lstrcpy( strModemString, "" );
  701.         if( GetDlgItemText( hWnd, IDC_MODEMCOMBO, strModemString, NAMEMAX ) )
  702.         {
  703.             addressElements[dwElementCount].guidDataType = DPAID_Modem;
  704.             addressElements[dwElementCount].dwDataSize   = lstrlen(strModemString) + 1;
  705.             addressElements[dwElementCount].lpData       = strModemString;
  706.             dwElementCount++;
  707.         }
  708.  
  709.         // Add phone number string
  710.         lstrcpy( strPhoneNumberString, "" );
  711.         GetDlgItemText(hWnd, IDC_PHONEEDIT, strPhoneNumberString, NAMEMAX);
  712.         addressElements[dwElementCount].guidDataType = DPAID_Phone;
  713.         addressElements[dwElementCount].dwDataSize   = lstrlen(strPhoneNumberString) + 1;
  714.         addressElements[dwElementCount].lpData       = strPhoneNumberString;
  715.         dwElementCount++;
  716.     }
  717.     else if( IsEqualGUID( guidServiceProvider, DPSPGUID_TCPIP ) )
  718.     {
  719.         // TCP/IP needs a service provider, an IP address, and optional port #
  720.  
  721.         // Service provider
  722.         addressElements[dwElementCount].guidDataType = DPAID_ServiceProvider;
  723.         addressElements[dwElementCount].dwDataSize   = sizeof(GUID);
  724.         addressElements[dwElementCount].lpData       = (VOID*)&DPSPGUID_TCPIP;
  725.         dwElementCount++;
  726.  
  727.         // IP address string
  728.         lstrcpy( strIPAddressString, "" );
  729.         GetDlgItemText(hWnd, IDC_TCPEDIT, strIPAddressString, NAMEMAX);
  730.         addressElements[dwElementCount].guidDataType = DPAID_INet;
  731.         addressElements[dwElementCount].dwDataSize   = lstrlen(strIPAddressString) + 1;
  732.         addressElements[dwElementCount].lpData       = strIPAddressString;
  733.         dwElementCount++;
  734.  
  735.         // Optional Port number
  736.         wPort = (WORD)GetDlgItemInt( hWnd, IDC_PORTEDIT, NULL, FALSE );
  737.         if( wPort > 0 )
  738.         {
  739.             addressElements[dwElementCount].guidDataType = DPAID_INetPort;
  740.             addressElements[dwElementCount].dwDataSize   = sizeof(WORD);
  741.             addressElements[dwElementCount].lpData       = &wPort;
  742.             dwElementCount++;
  743.         }
  744.     }
  745.     else if( IsEqualGUID( guidServiceProvider, DPSPGUID_IPX ) )
  746.     {
  747.         // IPX just needs a service provider
  748.  
  749.         // Service provider
  750.         addressElements[dwElementCount].guidDataType = DPAID_ServiceProvider;
  751.         addressElements[dwElementCount].dwDataSize   = sizeof(GUID);
  752.         addressElements[dwElementCount].lpData       = (VOID*)&DPSPGUID_IPX;
  753.         dwElementCount++;
  754.     }
  755.     else
  756.     {
  757.         // Anything else, let service provider collect settings, if any
  758.         
  759.         // Service provider
  760.         addressElements[dwElementCount].guidDataType = DPAID_ServiceProvider;
  761.         addressElements[dwElementCount].dwDataSize   = sizeof(GUID);
  762.         addressElements[dwElementCount].lpData       = (VOID*)&guidServiceProvider;
  763.         dwElementCount++;
  764.     }
  765.  
  766.     // See how much room is needed to store this address
  767.     hr = pDPLobby->CreateCompoundAddress( addressElements, dwElementCount,
  768.                                           NULL, &dwAddressSize );
  769.     if( hr != DPERR_BUFFERTOOSMALL )
  770.         return hr;
  771.  
  772.     // Allocate space
  773.     pAddress = GlobalAllocPtr( GHND, dwAddressSize );
  774.     if( pAddress == NULL )
  775.         return DPERR_NOMEMORY;
  776.  
  777.     // Create the address
  778.     hr = pDPLobby->CreateCompoundAddress( addressElements, dwElementCount,
  779.                                           pAddress, &dwAddressSize );
  780.     if( FAILED(hr) )
  781.     {
  782.         GlobalFreePtr( pAddress );
  783.         return hr;
  784.     }
  785.  
  786.     // Return the address info
  787.     *ppAddress = pAddress;
  788.     *pdwAddressSize = dwAddressSize;
  789.  
  790.     return DP_OK;
  791. }
  792.  
  793.  
  794.  
  795.  
  796. //-----------------------------------------------------------------------------
  797. // Name: DoHostOrJoin()
  798. // Desc: 
  799. //-----------------------------------------------------------------------------
  800. HRESULT DoHostOrJoin( HINSTANCE hInstance, HWND hWnd,
  801.                       LPDIRECTPLAYLOBBY3A pDPLobby, BOOL bHost,
  802.                       LPDIRECTPLAY4A* ppDP )
  803. {
  804.     LPDIRECTPLAY4A pDP           = NULL;
  805.     VOID*          pAddress      = NULL;
  806.     DWORD          dwAddressSize = 0;
  807.     DPSESSIONDESC2 sessionDesc;
  808.     STATUSCONTEXT  statusContext;
  809.     HRESULT        hr;
  810.  
  811.     // Bail if we don't have a lobby interface
  812.     if( pDPLobby == NULL )
  813.         return DPERR_INVALIDOBJECT;
  814.  
  815.     // Get service provider address from information in dialog
  816.     hr = CreateServiceProviderAddress( hWnd, pDPLobby, &pAddress,
  817.                                        &dwAddressSize );
  818.     if( FAILED(hr) )
  819.         return hr;
  820.  
  821.     // interface already exists, so release it
  822.     if( *ppDP )
  823.     {
  824.         (*ppDP)->Close();
  825.         (*ppDP)->Release();
  826.         *ppDP = NULL;
  827.     }
  828.  
  829.     // Create an ANSI DirectPlay4 interface
  830.     hr = CoCreateInstance( CLSID_DirectPlay, NULL, CLSCTX_INPROC_SERVER, 
  831.                            IID_IDirectPlay4A, (VOID**)&pDP );
  832.     if( FAILED(hr) )
  833.         return hr;
  834.  
  835.     // Initialize the connection using the address
  836.     hr = pDP->InitializeConnection( pAddress, 0 );
  837.     if( FAILED(hr) )
  838.     {
  839.         pDP->Release();
  840.         return hr;
  841.     }
  842.  
  843.     if( bHost )
  844.     {
  845.         // Host a new session
  846.         ZeroMemory( &sessionDesc, sizeof(DPSESSIONDESC2) );
  847.         sessionDesc.dwSize  = sizeof(DPSESSIONDESC2);
  848.         sessionDesc.dwFlags = DPSESSION_MIGRATEHOST | DPSESSION_KEEPALIVE;
  849.         sessionDesc.guidApplication  = OVERRIDE_GUID;
  850.         sessionDesc.dwMaxPlayers     = 0;
  851.         sessionDesc.lpszSessionNameA = "Override";
  852.  
  853.         // Open it
  854.         hr = pDP->Open( &sessionDesc, DPOPEN_CREATE );
  855.     }
  856.     else
  857.     {
  858.         // Enumerate the sessions
  859.         // Display status dialog and enumerate until we find a session
  860.         statusContext.pDP = pDP;
  861.         statusContext.guidInstance = GUID_NULL;
  862.  
  863.         if( !DialogBoxParam( hInstance, MAKEINTRESOURCE(IDD_SESSIONSDIALOG),
  864.                              hWnd, (DLGPROC)SessionsWndProc, (LPARAM)&statusContext ) )
  865.         {
  866.             pDP->Release();
  867.             return DPERR_USERCANCEL;
  868.         }
  869.  
  870.         // Open the session selected by the use
  871.         ZeroMemory( &sessionDesc, sizeof(DPSESSIONDESC2) );
  872.         sessionDesc.dwSize          = sizeof(DPSESSIONDESC2);
  873.         sessionDesc.guidApplication = OVERRIDE_GUID;
  874.         sessionDesc.guidInstance    = statusContext.guidInstance;
  875.  
  876.         // Open it
  877.         hr = pDP->Open( &sessionDesc, DPOPEN_JOIN );
  878.     }
  879.  
  880.     if( FAILED(hr) )
  881.     {
  882.         pDP->Close();
  883.         pDP->Release();
  884.         return hr;
  885.     }
  886.  
  887.     // Return the connected interface
  888.     *ppDP = pDP;
  889.  
  890.     return DP_OK;
  891. }
  892.  
  893.  
  894.  
  895.  
  896. //-----------------------------------------------------------------------------
  897. // Name: EnumModemAddress()
  898. // Desc: Enumerates the DirectPlay address chunks. If the chunk contains modem
  899. //       strings, add them to the control.
  900. //-----------------------------------------------------------------------------
  901. BOOL FAR PASCAL EnumModemAddress( REFGUID guidDataType, DWORD dwDataSize,
  902.                                   const VOID* pData, VOID* pContext )
  903. {
  904.     HWND  hWnd   = (HWND)pContext;
  905.     LPSTR strStr = (LPSTR)pData;
  906.  
  907.     // Modem
  908.     if( IsEqualGUID( guidDataType, DPAID_Modem ) )
  909.     {
  910.         // Loop over all strings in list
  911.         while( lstrlen( strStr ) )
  912.         {
  913.             // Store modem name in combo box
  914.             SendDlgItemMessage( hWnd, IDC_MODEMCOMBO, CB_ADDSTRING, 0,
  915.                                 (LPARAM)strStr );
  916.  
  917.             // Skip to next string
  918.             strStr += lstrlen(strStr) + 1;
  919.         }
  920.     }
  921.  
  922.     return TRUE;
  923. }
  924.  
  925.  
  926.  
  927.  
  928. //-----------------------------------------------------------------------------
  929. // Name: FillModemComboBox()
  930. // Desc: Fills combo box with modem names
  931. //-----------------------------------------------------------------------------
  932. HRESULT FillModemComboBox( HWND hWnd, LPDIRECTPLAYLOBBY3A pDPLobby )
  933. {
  934.     LPDIRECTPLAY   pDP1 = NULL;
  935.     LPDIRECTPLAY4A pDP = NULL;
  936.     VOID*          pAddress = NULL;
  937.     DWORD          dwAddressSize = 0;
  938.     GUID           guidServiceProvider = DPSPGUID_MODEM;
  939.     HRESULT        hr;
  940.  
  941.     // Use the obsolete DirectPlayCreate() as quick way to load a specific
  942.     // service provider.  Trade off using DirectPlayCreate() and
  943.     // QueryInterface() vs using CoCreateInitialize() and building a
  944.     // DirectPlay Address for InitializeConnection().
  945.     hr = DirectPlayCreate( &guidServiceProvider, &pDP1, NULL );
  946.     if( FAILED(hr) )
  947.         return hr;
  948.  
  949.     // Query for an ANSI DirectPlay4 interface
  950.     hr = pDP1->QueryInterface( IID_IDirectPlay4A, (VOID**)&pDP );
  951.     if( FAILED(hr) )
  952.     {
  953.         pDP1->Release();
  954.         return hr;
  955.     }
  956.  
  957.     // Get size of player address for player zero
  958.     hr = pDP->GetPlayerAddress( DPID_ALLPLAYERS, NULL, &dwAddressSize );
  959.     if( hr != DPERR_BUFFERTOOSMALL )
  960.     {
  961.         pDP1->Release();
  962.         pDP->Release();
  963.         return hr;
  964.     }
  965.  
  966.     // Make room for it
  967.     pAddress = GlobalAllocPtr( GHND, dwAddressSize );
  968.     if( pAddress == NULL )
  969.     {
  970.         pDP1->Release();
  971.         pDP->Release();
  972.         return DPERR_NOMEMORY;
  973.     }
  974.  
  975.     // Get the address
  976.     hr = pDP->GetPlayerAddress( DPID_ALLPLAYERS, pAddress, &dwAddressSize );
  977.     if( FAILED(hr) )
  978.     {
  979.         pDP1->Release();
  980.         pDP->Release();
  981.         if( pAddress )
  982.             GlobalFreePtr( pAddress );
  983.         return hr;
  984.     }
  985.     
  986.     // Get modem strings from address and put them in the combo box
  987.     hr = pDPLobby->EnumAddress( EnumModemAddress, pAddress, dwAddressSize, hWnd );
  988.     if( FAILED(hr) )
  989.     {
  990.         pDP1->Release();
  991.         pDP->Release();
  992.         if( pAddress )
  993.             GlobalFreePtr( pAddress );
  994.         return hr;
  995.     }
  996.  
  997.     // Select first item in list
  998.     SendDlgItemMessage( hWnd, IDC_MODEMCOMBO, CB_SETCURSEL, 0, 0 );
  999.  
  1000.     // Cleanup and return
  1001.     pDP1->Release();
  1002.     pDP->Release();
  1003.     if( pAddress )
  1004.         GlobalFreePtr( pAddress );
  1005.     
  1006.     return DP_OK;
  1007. }
  1008.  
  1009.  
  1010.  
  1011.  
  1012. //-----------------------------------------------------------------------------
  1013. // Name: DlgItemIsChecked()
  1014. // Desc: 
  1015. //-----------------------------------------------------------------------------
  1016. BOOL DlgItemIsChecked( HWND hDlg, int nIDDlgItem )
  1017. {
  1018.     return( ( SendDlgItemMessage( hDlg, nIDDlgItem, BM_GETCHECK, 0, 0)
  1019.               == BST_CHECKED) ? TRUE : FALSE );
  1020. }
  1021.  
  1022.  
  1023.  
  1024.  
  1025. //-----------------------------------------------------------------------------
  1026. // Name: EnableDlgButton()
  1027. // Desc: 
  1028. //-----------------------------------------------------------------------------
  1029. VOID EnableDlgButton( HWND hDlg, int nIDDlgItem, BOOL bEnable )
  1030. {
  1031.     EnableWindow( GetDlgItem( hDlg, nIDDlgItem ), bEnable );
  1032. }
  1033.  
  1034.  
  1035.  
  1036.  
  1037. //-----------------------------------------------------------------------------
  1038. // Name: ErrorBox()
  1039. // Desc: 
  1040. //-----------------------------------------------------------------------------
  1041. VOID ErrorBox( LPSTR strError, HRESULT hr )
  1042. {
  1043.     CHAR str[MAXSTRLEN];
  1044.  
  1045.     wsprintf( str, strError, hr );
  1046.     MessageBox(NULL, str, "DPLaunch Error", MB_OK );
  1047. }
  1048.  
  1049.  
  1050.  
  1051.